using Server.Engines.Quests;
using Server.Mobiles;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Server.Items
{
    public class NestWithEgg : BaseAddon
    {
        public TimeSpan ResetPeriod => TimeSpan.FromSeconds(Utility.RandomMinMax(120, 360));

        public List<BaseCreature> Poachers { get; set; }
        public List<Mobile> FocusList { get; set; }
        public BaseCreature Hatchling { get; set; }
        public Mobile Focus { get; set; }
        public bool IsHatching { get; set; }
        public DateTime CooldownEnds { get; set; }

        public Timer DeadlineTimer { get; set; }

        public AddonComponent Egg => Components.FirstOrDefault(c => c.ItemID == 16831);

        public bool IsInCooldown => CooldownEnds != DateTime.MinValue && DateTime.UtcNow < CooldownEnds;

        [Constructable]
        public NestWithEgg()
        {
            AddonComponent comp = new LocalizedAddonComponent(3518, 1026869)
            {
                Hue = 449
            };
            AddComponent(comp, 0, 0, 0);

            comp = new LocalizedAddonComponent(3270, 1026869)
            {
                Hue = 551
            };
            AddComponent(comp, 0, 0, 2);

            comp = new LocalizedAddonComponent(3374, 1026869)
            {
                Hue = 551
            };
            AddComponent(comp, 0, 0, 2);

            comp = new LocalizedAddonComponent(16831, 1112469);
            AddComponent(comp, 1, 1, 15);

            FocusList = new List<Mobile>();
        }

        public override bool HandlesOnMovement => !IsInCooldown;
        public override void OnMovement(Mobile m, Point3D oldLocation)
        {
            if (m is PlayerMobile && m.Location != oldLocation && m.InRange(Location, 3) && (!FocusList.Contains(m) || 0.015 > Utility.RandomDouble()))
            {
                EmptyNestQuest quest = QuestHelper.GetQuest((PlayerMobile)m, typeof(EmptyNestQuest)) as EmptyNestQuest;

                if (quest != null && !quest.Completed)
                {
                    if (Focus == null)
                    {
                        Focus = m;
                        m.RevealingAction();
                        SpawnPoachers(m);

                        DeadlineTimer = Timer.DelayCall(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5), () =>
                        {
                            DeadlineTimer.Stop();

                            if (Poachers != null && Poachers.Count > 0)
                                Delete();
                            else
                            {
                                Focus = null;
                                Hatchling = null;
                                CooldownEnds = DateTime.MinValue;
                            }
                        });

                        DeadlineTimer.Start();
                    }
                    else if (IsInCooldown)
                    {
                        CooldownEnds = DateTime.UtcNow + TimeSpan.FromMinutes(2);
                    }
                }
            }
        }

        public void SpawnPoachers(Mobile m)
        {
            Map map = m.Map;

            if (map == null || map == Map.Internal)
                return;

            if (Poachers == null)
                Poachers = new List<BaseCreature>();

            for (int i = 0; i < 3; i++)
            {
                Poacher p = new Poacher(this);
                Point3D pnt = m.Location;

                for (int j = 0; j < 10; j++)
                {
                    int x = Utility.RandomMinMax(m.X - 2, m.X + 2);
                    int y = Utility.RandomMinMax(m.Y - 2, m.Y + 2);
                    int z = map.GetAverageZ(x, y);

                    if (map.CanSpawnMobile(x, y, z))
                    {
                        pnt = new Point3D(x, y, z);
                        break;
                    }
                }

                p.MoveToWorld(pnt, map);
                Poachers.Add(p);
            }

            Poachers.ForEach(poacher => poacher.Combatant = m);
        }

        public void OnPoacherKilled(BaseCreature bc)
        {
            if (Poachers != null && Poachers.Contains(bc))
            {
                Poachers.Remove(bc);

                if (Poachers.Count == 0)
                {
                    if (!IsHatching)
                    {
                        IsHatching = true;
                        ColUtility.Free(Poachers);

                        Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(15, 30)), () =>
                        {
                            Hatchling = new DragonTurtleHatchling();
                            Hatchling.MoveToWorld(Location, Map);
                            Hatchling.Tamable = false;

                            SpawnPoachers(Hatchling);

                            if (Egg != null)
                                Egg.Visible = false;
                        });
                    }
                    else
                    {
                        if (Hatchling.Alive)
                        {
                            CooldownEnds = DateTime.UtcNow + ResetPeriod;
                            Timer.DelayCall(TimeSpan.FromSeconds(1), OnComplete, new object[] { Hatchling, Focus });

                            if (!FocusList.Contains(Focus))
                                FocusList.Add(Focus);
                        }
                        else
                            Delete();

                        if (DeadlineTimer != null)
                        {
                            DeadlineTimer.Stop();
                            DeadlineTimer = null;
                        }

                        Hatchling = null;
                        Focus = null;

                        ColUtility.Free(Poachers);
                        Poachers = null;
                    }
                }
            }
        }

        private void OnComplete(object o)
        {
            object[] objs = o as object[];
            BaseCreature hatchling = objs[0] as BaseCreature;
            Mobile focus = objs[1] as Mobile;

            if (hatchling != null)
            {
                focus.PublicOverheadMessage(Network.MessageType.Regular, 0x35, 1156496); // *The Hatchling safely burrows into the sand*
                Timer.DelayCall(TimeSpan.FromSeconds(1), hatchling.Delete);
            }

            if (focus != null && focus is PlayerMobile)
            {
                EmptyNestQuest quest = QuestHelper.GetQuest((PlayerMobile)focus, typeof(EmptyNestQuest)) as EmptyNestQuest;

                if (quest != null)
                {
                    quest.Update(hatchling);
                    // Quest Complete and crap can be handled in update
                }
            }

            Timer.DelayCall(TimeSpan.FromMinutes(1), () =>
            {
                if (Egg != null && !Egg.Visible)
                    Egg.Visible = true;
            });

            IsHatching = false;
        }

        public override void Delete()
        {
            base.Delete();

            if (DeadlineTimer != null)
            {
                DeadlineTimer.Stop();
                DeadlineTimer = null;
            }

            if (Poachers != null)
                ColUtility.Free(Poachers);
        }

        public NestWithEgg(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write(0);
            writer.Write(Hatchling);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
            Hatchling = reader.ReadMobile() as BaseCreature;

            if (Hatchling != null)
                Hatchling.Delete();

            if (Egg != null && !Egg.Visible)
                Egg.Visible = true;

            FocusList = new List<Mobile>();
        }
    }
}